﻿using CuteSprite.Eme.Data.BsdUserCenter;
using CuteSprite.Eme.Data.CRM;
using CuteSprite.Eme.Data.Settlement;
using CuteSprite.Eme.UI.Utils;
using HmFramework.Components;
using HmFramework.Components.Controls;
using HmFramework.Components.Editors.DateTimeAdv;
using HmFramework.Data;
using HmFramework.Log;
using System;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using EmeSettlement = CuteSprite.Eme.Data.Settlement.Settlement;

namespace CuteSprite.Eme.UI.Settlement
{
	public partial class FrmBsdSettlement : EmeEntityForm
	{
		#region -- Fields --

		private ExpressSettlementFuelModel m_fuelmodel = ExpressSettlementFuelModel.None;

		/// <summary>运单号是否修改，是否触发leave事件</summary>
		private String m_oldExpressNo = String.Empty;

		/// <summary>空公布价方案</summary>
		private SettlementSolution m_nullSolution = new SettlementSolution();

		/// <summary>应为默认方案一定是第一条记录，可以模拟生成，所以不去获取</summary>
		private SettlementSolution m_dsSolution = new SettlementSolution();

		/// <summary>异步匹配时所用</summary>
		private ExpressBusinessCategory m_businessCategoryEnum;

		/// <summary>异步匹配时所用</summary>
		private String m_expressNo;

		/// <summary>异步匹配时所用</summary>
		private Boolean m_isSpecial = false;

		/// <summary>异步匹配时所用，所结算的运单</summary>
		private IEntity m_currentExpress = null;

		/// <summary>异步匹配时所用，运单所属客户</summary>
		private BsdCustomer m_currentCustomer = null;

		/// <summary>是否触发公布价方案列表控件选中值改变事件</summary>
		private Boolean m_canRaiseSettlementSolutionChangedEvent = true;

		/// <summary>异步匹配公布价方案时使用，公布价方案ID</summary>
		private Int32 m_selSettlementSolutionID;

		/// <summary>结算匹配错误信息</summary>
		private String m_errorMsg = null;

		private String m_errorMsgP = null;

		#endregion

		#region -- 属性 --

		private EmeSettlement _CurrentSettlement;

		/// <summary>当前结算实体</summary>
		public EmeSettlement CurrentSettlement
		{
			get
			{
				if (_CurrentSettlement != null) { return _CurrentSettlement; }
				_CurrentSettlement = CurrentEntity as EmeSettlement;
				return _CurrentSettlement;
			}
			set { _CurrentSettlement = value; }
		}

		private EntityList<SettlementSolution> _CurrentSettlementSolutions = new EntityList<SettlementSolution>();

		/// <summary>当前结算记录所用的公布价方案列表，包括一个空公布价方案、默认公布价方案、运单所属客户所拥有的公布价方案列表</summary>
		public EntityList<SettlementSolution> CurrentSettlementSolutions
		{
			get { return _CurrentSettlementSolutions; }
			set { _CurrentSettlementSolutions = value; }
		}

		#endregion

		#region -- 构造 --

		#region - 新增 -

		/// <summary>默认构造函数</summary>
		public FrmBsdSettlement()
			: base()
		{
			InitializeComponent();
			InitForm();
		}

		/// <summary>构造函数</summary>
		/// <param name="templateFileName">模板文件</param>
		public FrmBsdSettlement(String templateFileName)
		{
			SetupFromXml(templateFileName);
			InitForm();
		}

		/// <summary>构造函数</summary>
		/// <param name="resourceName">模板资源文件</param>
		/// <param name="asm">模板资源文件所在程序集</param>
		public FrmBsdSettlement(String resourceName, Assembly asm)
		{
			SetupFromXmlResource(resourceName, asm);
			InitForm();
		}

		/// <summary>构造函数</summary>
		/// <param name="stream">模板数据流</param>
		public FrmBsdSettlement(Stream stream)
		{
			SetupFromXmlStream(stream);
			InitForm();
		}

		#endregion - 新增 -

		#region - 编辑或新增 -

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		public FrmBsdSettlement(IEntity entity)
			: this(entity, false)
		{
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="readOnly">是否只读，指定编辑还是浏览实体信息</param>
		public FrmBsdSettlement(IEntity entity, Boolean readOnly)
			: base(entity, readOnly)
		{
			InitializeComponent();
			InitForm();
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="templateFileName">模板文件</param>
		public FrmBsdSettlement(IEntity entity, String templateFileName)
			: this(entity, templateFileName, false)
		{
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="templateFileName">模板文件</param>
		/// <param name="readOnly">是否只读，指定编辑还是浏览实体信息</param>
		public FrmBsdSettlement(IEntity entity, String templateFileName, Boolean readOnly)
			: base(entity, readOnly)
		{
			SetupFromXml(templateFileName);

			InitForm();
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="resourceName">模板资源文件</param>
		/// <param name="asm">模板资源文件所在程序集</param>
		public FrmBsdSettlement(IEntity entity, String resourceName, Assembly asm)
			: this(entity, resourceName, asm, false)
		{
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="resourceName">模板资源文件</param>
		/// <param name="asm">模板资源文件所在程序集</param>
		/// <param name="readOnly">是否只读，指定编辑还是浏览实体信息</param>
		public FrmBsdSettlement(IEntity entity, String resourceName, Assembly asm, Boolean readOnly)
			: base(entity, readOnly)
		{
			SetupFromXmlResource(resourceName, asm);

			InitForm();
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="stream">模板数据流</param>
		public FrmBsdSettlement(IEntity entity, Stream stream)
			: this(entity, stream, false)
		{
		}

		/// <summary>构造函数</summary>
		/// <param name="entity">实体对象</param>
		/// <param name="stream">模板数据流</param>
		/// <param name="readOnly">是否只读，指定编辑还是浏览实体信息</param>
		public FrmBsdSettlement(IEntity entity, Stream stream, Boolean readOnly)
			: base(entity, readOnly)
		{
			SetupFromXmlStream(stream);

			InitForm();
		}

		#endregion - 编辑或新增 -

		#endregion

		#region -- 窗体事件 --

		#region - method InitComponent -

		///// <summary>控件初始化</summary>
		protected override void InitComponent()
		{
			base.InitComponent();

			#region 运单号事件

			if (frmSettlementDate == null) { frmSettlementDate = FindControl("frmSettlementDate") as DateTimeInput; }
			if (frmExpressNo == null) { frmExpressNo = FindControl("frmExpressNo") as TextBoxX; }
			if (frmExpressNo != null)
			{
				frmExpressNo.Leave += new EventHandler((sender, e) =>
				{
					if (!IsAddNew) { return; }

					var expressNo = frmExpressNo.Text.Trim();
					///判断运单号是否修改，如果没修改则不重新做填充
					if (!m_oldExpressNo.Equals(expressNo))
					{
						m_oldExpressNo = frmExpressNo.Text;

						if (!GetFormValue())
						{
							if (!m_errorMsg.IsNullOrWhiteSpace())
							{
								MessageBoxEx.Show(m_errorMsg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
							}
						}
					}
				});
			}

			#endregion -- 运单号事件 --

			#region 业务类别事件

			if (frmBusinessCategory == null) { frmBusinessCategory = FindControl("frmBusinessCategory") as ComboBoxEx; }
			if (frmBusinessCategory != null)
			{
				frmBusinessCategory.SelectedIndexChanged += new EventHandler((sender, e) =>
				{
					if (!IsAddNew) { return; }

					if (!GetFormValue())
					{
						if (!m_errorMsg.IsNullOrWhiteSpace())
						{
							MessageBoxEx.Show(m_errorMsg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
						}
					}
				});
			}

			#endregion -- 业务类别事件 --

			#region 公布价方案事件

			if (frmSettlementSolutionID == null) { frmSettlementSolutionID = FindControl("frmSettlementSolutionID") as ComboBoxEx; }
			if (frmSettlementSolutionID != null)
			{
				frmSettlementSolutionID.SelectedIndexChanged += new EventHandler((sender, e) =>
				{
					if (!m_canRaiseSettlementSolutionChangedEvent) { return; }

					m_selSettlementSolutionID = Convert.ToInt32(frmSettlementSolutionID.SelectedValue);
					if (IsAddNew)
					{
						// 新增时，运单实体或客户实体为空，不做匹配
						if (m_currentCustomer == null || m_currentExpress == null) { return; }
					}
					if (!bgWorker.IsBusy && !bgWorkerP.IsBusy)
					{
						m_errorMsgP = null;
						EnableControls(false);
						bgWorkerP.RunWorkerAsync();
					}
				});
			}

			#endregion -- 公布价方案事件 --

			#region 燃油计费模式

			if (frmFuelModel == null) { frmFuelModel = FindControl("selectFuelModel") as ComboBoxEx; }
			if (frmFuelModel != null)
			{
				BindSystemStatusComboBox(frmFuelModel, "SettlementFuelModel");

				frmFuelModel.SelectedIndexChanged += new EventHandler((sender, e) =>
				{
					var selMode = Convert.ToInt32(frmFuelModel.SelectedValue);
					m_fuelmodel = (ExpressSettlementFuelModel)selMode;
					switch (m_fuelmodel)
					{
						case ExpressSettlementFuelModel.IncludedFuelCosts:
							txtFuelData2.Visible = false;
							txtFuelData.Visible = true;
							txtFuelData.Enabled = false;
							txtFuelData.Text = "0";
							txtFuelData.Value = 0;
							break;

						case ExpressSettlementFuelModel.PercentageTotalBilling:
						case ExpressSettlementFuelModel.DiscountPercentageBilling:
							txtFuelData2.Visible = true;
							txtFuelData.Visible = false;
							txtFuelData.Enabled = true;
							break;

						case ExpressSettlementFuelModel.Cash:
							txtFuelData2.Visible = false;
							txtFuelData.Visible = true;
							txtFuelData.Enabled = true;
							txtFuelData.Value = 0;
							break;

						default:
							txtFuelData2.Visible = false;
							txtFuelData.Visible = true;
							txtFuelData.Enabled = false;
							txtFuelData.Value = 0;
							txtFuelData.Text = "0";
							break;
					}
				});
			}

			#endregion

			this.OnValid += new System.EventHandler<CuteSprite.Eme.UI.Utils.EntityFormEventArgs>(this.FrmSettlement_OnValid);
			this.OnSaving += new System.EventHandler<CuteSprite.Eme.UI.Utils.EntityFormEventArgs>(this.FrmExpress_OnSaving);
		}

		#endregion - method InitComponent -

		#region - method FormOnPreLoad -

		protected override void FormOnPreLoad()
		{
			base.FormOnPreLoad();

			if (IsAddNew)
			{
				CurrentSettlement.SettlementDate = DateTime.Now;
			}

			// 空方案
			m_nullSolution = new SettlementSolution();
			m_nullSolution.ID = 0;
			m_nullSolution.Name = "-- 请选择 --";
			m_nullSolution.Code = "";
			// 应为默认方案一定是第一条记录，可以模拟生成，所以不去获取
			m_dsSolution = new SettlementSolution();
			m_dsSolution.ID = 1;
			m_dsSolution.Name = "默认方案";
			m_dsSolution.Code = "DS";

			m_canRaiseSettlementSolutionChangedEvent = false;
		}

		#endregion

		#region - method FormOnLoad -

		public override void FormOnLoad()
		{
			base.FormOnLoad();

			if (!IsAddNew)
			{
				if (CurrentSettlement.CustomerID > 0)
				{
					try
					{
						lock (ServerManagement.LockSynchronizer)
						{
							frmCustomerID2.Text = ServerManagement.Client.GetEntityFieldValue(
									EntityHelper.ModelUserCenter, EntityHelper.UserCenterTableCustomer, CurrentSettlement.CustomerID, BsdCustomer.____.Name);
						}
					}
					catch { }
				}
			}

			RefreshCurrentSettlementSolutions();

			m_canRaiseSettlementSolutionChangedEvent = true;
		}

		#endregion - method FormOnPreLoad -

		#region - 实体验证 -

		private void FrmSettlement_OnValid(object sender, EntityFormEventArgs e)
		{
			if (CurrentSettlement.BusinessCategory <= 0)
			{
				MessageBoxEx.Show("请选择结算业务类别！", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				e.Cancel = true;
				return;
			}

			if (CurrentSettlement.ExpressNo.IsNullOrWhiteSpace())
			{
				MessageBoxEx.Show("请输入结算运单号码！", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				e.Cancel = true;
				return;
			}

			if (CurrentSettlement.SettlementSolutionID <= 0)
			{
				MessageBoxEx.Show("请选择结算记录所使用的公布价方案！", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				e.Cancel = true;
				return;
			}

			// 是否有错，出错不可以保存；这里必须放在最后验证，考虑特殊计费模式
			if (!m_errorMsg.IsNullOrWhiteSpace())
			{
				MessageBoxEx.Show(m_errorMsg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				e.Cancel = true;
				return;
			}

			// 是否有错，出错不可以保存；这里必须放在最后验证，考虑特殊计费模式
			if (!m_errorMsgP.IsNullOrWhiteSpace())
			{
				MessageBoxEx.Show(m_errorMsgP, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				e.Cancel = true;
				return;
			}
		}

		#endregion

		#region - 实体保存 -

		private void FrmExpress_OnSaving(object sender, EntityFormEventArgs e)
		{
			//// 判断是否为特殊报价，特殊报价取控件值存储。
			//if (frmIsSpecial.Checked)
			//{
			//	CurrentSettlement.IsMultiPrice = checkIsMultiPrice.Checked;
			//	CurrentSettlement.PrimaryPrice = txtPrimaryPrice.Value;
			//	CurrentSettlement.ExtraPrice = txtExtraPrice.Value;
			//	CurrentSettlement.WeightBasedBilling = rbWeightBasedBilling2.Checked ? 1M : 0.5M;
			//	CurrentSettlement.FuelModel = (Int32)m_fuelmodel;
			//	CurrentSettlement.FuelData = txtFuelData.Value;
			//}
		}

		#endregion - 实体保存 -

		#endregion

		#region -- method RefreshCurrentSettlementSolutions --

		/// <summary>刷新公布价方案列表</summary>
		private void RefreshCurrentSettlementSolutions()
		{
			var oldFlag = m_canRaiseSettlementSolutionChangedEvent;

			m_canRaiseSettlementSolutionChangedEvent = false;

			CurrentSettlementSolutions.Clear();

			CurrentSettlementSolutions.AddRange(new SettlementSolution[] { m_nullSolution, m_dsSolution });

			if (CurrentSettlement.CustomerID > 0)
			{
				try
				{
					lock (ServerManagement.LockSynchronizer)
					{
						//frmCustomerID2.Text = ServerManagement.Client.GetEntityFieldValue(EntityHelper.ModelUserCenter, EntityHelper.UserCenterTableCustomer, CurrentSettlement.CustomerID, BsdCustomer.__.Name);

						var entityName = BsdEntityHelper.SSTableSettlementSolution;
						var settlementsolution = ServerManagement.LoadEntityByKey(SettlementSolution.Meta.Factory, BsdEntityHelper.ModelSettlement, entityName, CurrentSettlement.SettlementSolutionID) as SettlementSolution;
						//判断是否存在客户默认的公布价，存在添加到列表
						if (settlementsolution != null && settlementsolution.Code != "DS")
						{
							CurrentSettlementSolutions.Add(settlementsolution);
						}

						//// 获取公布价方案客户表实体工厂
						//var sscFactory = EmeEntityFactory.Create(BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableSettlementSolutionAndCustomer);
						////Temp
						//var exp = sscFactory.MakeEqual(SettlementSolutionAndCustomer._.CustomerID, CurrentSettlement.CustomerID);
						//var order = sscFactory.MakeOrder(SettlementSolutionAndCustomer._.CreateOn, true);
						//var list = EmeRemotingHelper.FindEntityList(
						//    BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableSettlementSolutionAndCustomer,
						//    exp, order, null, 0, 0);
						//if (list.Count > 0 && list.DataSet != null)
						//{
						//  CurrentSettlementSolutions.AddRange(SettlementSolution.LoadData(list.DataSet));
						//}
					}
				}
				catch (Exception ex)
				{
					HmTrace.WriteWarn(ex.ToString());
					m_errorMsg = "无法读取客户公布价方案列表，连接服务器失败！";
					//DialogHelper.ShowWarning(null, ex.Message);
				}
			}
			frmSettlementSolutionID.DataSource = null;
			frmSettlementSolutionID.ValueMember = EntityHelper.FieldPrimaryID;
			frmSettlementSolutionID.DisplayMember = SettlementSolution.__.Name;
			frmSettlementSolutionID.DataSource = CurrentSettlementSolutions;
			frmSettlementSolutionID.SelectedValue = CurrentSettlement.SettlementSolutionID;

			m_canRaiseSettlementSolutionChangedEvent = oldFlag;
		}

		#endregion

		#region -- method GetFormValue --

		/// <summary>通过业务类别和运单号 查询所有表单信息填充</summary>
		private Boolean GetFormValue()
		{
			// 首先置空错误信息
			m_errorMsg = null;

			m_expressNo = frmExpressNo.Text.Trim();
			if (m_expressNo.IsNullOrWhiteSpace()) { return false; }
			var selBusinessCategory = (Int32)frmBusinessCategory.SelectedValue;
			if (selBusinessCategory <= 0) { return false; }

			EmeSettlement settlement = null;

			// 判断运单号是否存在结算记录
			try
			{
				lock (ServerManagement.LockSynchronizer)
				{
					var exp = CurrentEntityFactory.MakeEqual(EmeSettlement._.BusinessCategory, selBusinessCategory) &
										CurrentEntityFactory.MakeEqual(EmeSettlement._.ExpressNo, m_expressNo);
					//var exp2 = CurrentEntityFactory.MakeEqual(EmeSettlement._.IsDelete, 0);
					settlement = ServerManagement.LoadEntityWithClause(EmeSettlement.Meta.Factory, BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableSettlement, exp) as EmeSettlement;
				}
			}
			catch { SetErrorMsg("检测结算记录失败，连接服务器失败！"); return false; }

			if (settlement != null)
			{
				frmExpressNo.Focus();
				SetErrorMsg("此运单的结算记录已存在，请重新输入！"); return false;
			}

			m_businessCategoryEnum = (ExpressBusinessCategory)selBusinessCategory;

			if (!bgWorker.IsBusy && !bgWorkerP.IsBusy)
			{
				EnableControls(false);
				bgWorker.RunWorkerAsync();
			}

			return true;
		}

		#endregion

		#region -- method FillPriceInfos --

		/// <summary>根据公布价方案自动匹配结算信息</summary>
		/// <param name="settlementSolution">公布价方案实体</param>
		/// <returns></returns>
		private Boolean FillPriceInfos(SettlementSolution settlementSolution)
		{
			CurrentSettlement.SettlementSolutionID = settlementSolution.ID;

			#region 计费方案

			var billingFactory = EmeEntityFactory.Create(BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableBillingSolution);
			var billingExp = billingFactory.MakeEqual(BillingSolution._.SettlementSolutionID, settlementSolution.ID) &
											 billingFactory.MakeEqual(BillingSolution._.BusinessCategory, CurrentSettlement.BusinessCategory) &
											 billingFactory.MakeEqual(BillingSolution._.GoodsCategory, CurrentSettlement.GoodsCategory) &
											 billingFactory.MakeEqual(BillingSolution._.Region, CurrentSettlement.Region);
			var billingSolution = ServerManagement.LoadEntityWithClause(
					BillingSolution.Meta.Factory, BsdEntityHelper.ModelSettlement,
					BsdEntityHelper.SSTableBillingSolution, billingExp) as BillingSolution;
			if (billingSolution == null) { SetErrorMsg("计费方案为空，请完善公布价方案中的计费方案、计费价格方案信息！", true); return false; }

			#endregion

			#region 获取计费价格

			var priceFactory = EmeEntityFactory.Create(BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableBillingPrice);
			var priceExp = priceFactory.MakeEqual(BillingPrice._.ID, billingSolution.BillingPriceID);
			var billingPrice = ServerManagement.LoadEntityWithClause(
					BillingPrice.Meta.Factory, BsdEntityHelper.ModelSettlement,
					BsdEntityHelper.SSTableBillingPrice, priceExp) as BillingPrice;
			if (billingPrice == null) { SetErrorMsg("计费价格为空，请完善公布价方案中的计费方案、计费价格信息！", true); return false; }

			#endregion

			#region 填充计费价格明细信息

			EntityList<BillingPriceDetail> billingPriceDetails = null;

			var PriceDetailFactory = EmeEntityFactory.Create(BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableBillingPriceDetail);
			var PriceDetailExp = PriceDetailFactory.MakeEqual(BillingPriceDetail._.BillingPriceID, billingPrice.ID);

			try
			{
				var cache = EmeRemotingHelper.FindEntityList(BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableBillingPriceDetail, PriceDetailExp);
				if (cache != null)
				{
					billingPriceDetails = cache.FindAll() as EntityList<BillingPriceDetail>;
				}
			}
			catch { SetErrorMsg("无法获取计费价格方案信息，连接服务器失败！", true); return false; }

			// 计费价格方案为空，返回priceSolution
			if (billingPriceDetails == null) { SetErrorMsg("计费价格明细表为空，请完善公布价方案中的计费价格明细表信息！", true); return false; }

			if (billingPriceDetails != null && billingPriceDetails.Count > 0)
			{
				var billing = billingPriceDetails.Find(ss => ss.Weight == CurrentSettlement.SettleWeight);
				if (billing == null) { SetErrorMsg("计费价格明细表" + CurrentSettlement.SettleWeight + "重量段的价格信息，请完善公布价方案中的计费价格明细表信息！", true); return false; }
				CurrentSettlement.Price = billing.Price;
				CurrentSettlement.CompanyDiscount = billing.CompanyDiscount;
				CurrentSettlement.DepartmentDiscount = billing.DepartmentDiscount;
				CurrentSettlement.CustomerDiscount = billing.CustomerDiscount;
			}


			#endregion

			#region 获取附加费用

			var additionalFactory = EmeEntityFactory.Create(BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableAdditionalCost);
			var additionalExp = additionalFactory.MakeEqual(AdditionalCost._.ID, billingSolution.AdditionalChargesID);
			var additionalCost = ServerManagement.LoadEntityWithClause(
					AdditionalCost.Meta.Factory, BsdEntityHelper.ModelSettlement,
					BsdEntityHelper.SSTableAdditionalCost, additionalExp) as AdditionalCost;

			if (additionalCost == null) { SetErrorMsg("附加费用为空，请完善计费方案中的附加费用、计费价格信息！", true); return false; }

			CurrentSettlement.FuelData = additionalCost.FuelData;
			CurrentSettlement.FuelModel = additionalCost.FuelModel;
			CurrentSettlement.FareCustomsHK = additionalCost.FareCustomsHK;
			CurrentSettlement.CustomsDeclarationCost = additionalCost.CustomsDeclarationCost;
			CurrentSettlement.WarehousingTemporary = additionalCost.WarehousingTemporary;
			CurrentSettlement.OtherCost = additionalCost.OtherCost;

			#endregion

			return true;
		}

		#endregion

		#region -- method SetErrorMsg --

		private void SetErrorMsg(String message, Boolean setP = false)
		{
			m_errorMsg = message;
			if (setP) { m_errorMsgP = message; }
		}

		#endregion

		#region -- method SetWeight --

		/// <summary>
		/// 获取格式化重量，原始重量
		/// </summary>
		/// <param name="category">业务类别</param>
		/// <param name="entity"></param>
		private bool SetWeight(ExpressBusinessCategory category, IEntity entity)
		{
			switch (category)
			{
				case ExpressBusinessCategory.ExpressOCS:
					var express = entity as Express;
					CurrentSettlement.ProtoSettleWeight = Math.Max(express.SettleWeight, express.SettleVolWeight);
					CurrentSettlement.ProtoCustomerWeight = Math.Max(express.ReceWeight, express.ReceVolWeight);
					CurrentSettlement.ProtoDepartmentWeight = Math.Max(express.ProfitWeight, express.ProfitVolWeight);
					if (CurrentSettlement.ProtoCustomerWeight <= 0M) { SetErrorMsg("客户重量为0，无法进行结算！"); return false; }
					if (CurrentSettlement.ProtoDepartmentWeight <= 0M) { SetErrorMsg("部门重量为0，无法进行结算！"); return false; }
					if (CurrentSettlement.ProtoSettleWeight <= 0M) { SetErrorMsg("结算重量为0，无法进行结算！"); return false; }

					CurrentSettlement.SettleWeight = Express.FormatWeight(CurrentSettlement.ProtoSettleWeight);
					CurrentSettlement.CustomerWeight = Express.FormatWeight(CurrentSettlement.ProtoCustomerWeight);
					CurrentSettlement.DepartmentWeight = Express.FormatWeight(CurrentSettlement.ProtoDepartmentWeight);
					break;

				case ExpressBusinessCategory.ExpressEconomyLine:
					var expressEconomyLine = entity as ExpressEconomyLine;
					CurrentSettlement.ProtoSettleWeight = Math.Max(expressEconomyLine.SettleWeight, expressEconomyLine.SettleVolWeight);
					CurrentSettlement.ProtoCustomerWeight = Math.Max(expressEconomyLine.ReceWeight, expressEconomyLine.ReceVolWeight);
					CurrentSettlement.ProtoDepartmentWeight = Math.Max(expressEconomyLine.ProfitWeight, expressEconomyLine.ProfitVolWeight);
					CurrentSettlement.SettleWeight = Express.FormatWeight(CurrentSettlement.ProtoSettleWeight);
					CurrentSettlement.CustomerWeight = Express.FormatWeight(CurrentSettlement.ProtoCustomerWeight);
					CurrentSettlement.DepartmentWeight = Express.FormatWeight(CurrentSettlement.ProtoDepartmentWeight);
					break;

				case ExpressBusinessCategory.ExpressMix:
					var expressMix = entity as ExpressMix;
					CurrentSettlement.ProtoSettleWeight = Math.Max(expressMix.SettleWeight, expressMix.SettleVolWeight);
					CurrentSettlement.ProtoCustomerWeight = Math.Max(expressMix.ReceWeight, expressMix.ReceVolWeight);
					CurrentSettlement.ProtoDepartmentWeight = Math.Max(expressMix.ProfitWeight, expressMix.ProfitVolWeight);
					CurrentSettlement.SettleWeight = Express.FormatWeight(CurrentSettlement.ProtoSettleWeight);
					CurrentSettlement.CustomerWeight = Express.FormatWeight(CurrentSettlement.ProtoCustomerWeight);
					CurrentSettlement.DepartmentWeight = Express.FormatWeight(CurrentSettlement.ProtoDepartmentWeight);
					break;

				default:
					break;
			}
			return true;
		}

		#endregion

		#region -- method EnableControls --

		private void EnableControls(Boolean bEnabled)
		{
			if (SaveButton != null) { SaveButton.Enabled = bEnabled; }
			if (frmBusinessCategory != null) { frmBusinessCategory.Enabled = bEnabled; }
			if (frmExpressNo != null) { frmExpressNo.Enabled = bEnabled; }
			if (frmSettlementSolutionID != null) { frmSettlementSolutionID.Enabled = bEnabled; }
		}

		#endregion

		#region -- 后台自动匹配 --

		private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
		{
			#region 获取运单实体

			IEntity express = null;
			try
			{
				lock (ServerManagement.LockSynchronizer)
				{
					WhereExpression exp = null;
					String entityName = null;
					EmeEntityFactory expressFactory = null;
					switch (m_businessCategoryEnum)
					{
						case ExpressBusinessCategory.ExpressOCS:
							entityName = BsdEntityHelper.CrmTableExpress;
							expressFactory = EmeEntityFactory.Create(EntityHelper.ModelCrm, entityName);
							exp = expressFactory.MakeEqual(Express._.CWBNo, m_expressNo);
							break;

						case ExpressBusinessCategory.ExpressEconomyLine:
							entityName = BsdEntityHelper.CrmTableExpressEconomyLine;
							expressFactory = EmeEntityFactory.Create(EntityHelper.ModelCrm, entityName);
							exp = expressFactory.MakeEqual(Express._.CWBNo, m_expressNo);
							break;

						case ExpressBusinessCategory.ExpressMix:
							entityName = BsdEntityHelper.CrmTableExpressMix;
							expressFactory = EmeEntityFactory.Create(EntityHelper.ModelCrm, entityName);
							exp = expressFactory.MakeEqual(Express._.CWBNo, m_expressNo);
							break;
					}
					express = ServerManagement.LoadEntityWithClause(expressFactory.EntityOperate, EntityHelper.ModelCrm, entityName, exp);
				}
			}
			catch { SetErrorMsg("无法获取运单信息，连接服务器失败！"); return; }
			if (express == null) { SetErrorMsg("无法读取运单信息，请确认是否输入正确的运单号码！"); return; }
			m_currentExpress = express;

			#endregion

			#region 揽件人员、揽件部门、付款方式

			///从后台获取揽件人员，揽件部门、付款方式
			///

			#endregion

			#region 获取部门重量，客户重量、结算重量

			//获取部门重量，客户重量、结算重量
			if (!SetWeight(m_businessCategoryEnum, express)) { return; }

			#endregion

			#region 获取客户部门信息

			BsdCustomer customer = null;
			var customerID = Convert.ToInt32(express[Express.__.CustomerID]);
			if (customerID > 0)
			{
				// 获取客户信息
				customer = ServerManagement.LoadEntityByKey(BsdCustomer.Meta.Factory, EntityHelper.ModelUserCenter, EntityHelper.UserCenterTableCustomer, express[Express.__.CustomerID]) as BsdCustomer;
			}
			if (customer == null) { SetErrorMsg("运单的所属客户为空，请完善运单信息！"); return; }
			m_currentCustomer = customer;

			var organizeID = Convert.ToInt32(express[Express.__.OrganizeID]);
			if (organizeID <= 0) { SetErrorMsg("运单的所属部门为空，请完善运单信息！"); return; }

			CurrentSettlement.CustomerID = customerID;
			CurrentSettlement.CustomerDiscount = customer.SettlementDiscount;
			CurrentSettlement.CustomerAccount = customer.BackAccount;
			CurrentSettlement.OrganizeID = organizeID;
			#endregion

			//刷新公布价方案列表

			#region 获取公布价方案

			SettlementSolution settlementSolution = null;
			// 首先搜索客户默认的公布价方案

			settlementSolution = ServerManagement.LoadEntityByKey(SettlementSolution.Meta.Factory, BsdEntityHelper.ModelSettlement, BsdEntityHelper.SSTableSettlementSolution, customer.SettlementSolutionID) as SettlementSolution;

			//if (customer.SettlementSolutionID > 0)
			//{
			//  settlementSolution = CurrentSettlementSolutions.Find(ss => ss.ID == customer.SettlementSolutionID);
			//}
			// 接下来查询公布价方案数据表有没有所属客户的公布价方案
			//if (settlementSolution == null)
			//{
			//  if (CurrentSettlementSolutions.Count > 2) { settlementSolution = CurrentSettlementSolutions[2]; }
			//}
			// 使用默认方案
			if (settlementSolution == null) { settlementSolution = CurrentSettlementSolutions[1]; }

			#endregion

			#region 填充结算记录信息

			CurrentSettlement.BusinessCategoryEnum = m_businessCategoryEnum;
			CurrentSettlement.GoodsCategoryEnum = ("SPX" == Convert.ToString(express[Express.__.ExpressService])) ? ExpressGoodsCategory.SPX : ExpressGoodsCategory.DOX;
			CurrentSettlement.ExpressNo = m_expressNo;
			CurrentSettlement.Region = Convert.ToString(express[Express.__.ConsigneeCountryCode]);

			if (CurrentSettlement.Region == "") { SetErrorMsg("运单的地区为空，请完善运单信息！"); return; }


			//获取计费信息
			if (!FillPriceInfos(settlementSolution)) { return; }

			#endregion
		}

		private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			this.BeginInvoke(new MethodInvoker(() =>
			{
				m_canRaiseSettlementSolutionChangedEvent = false;
				RefreshCurrentSettlementSolutions();
				frmSettlementSolutionID.SelectedValue = CurrentSettlement.SettlementSolutionID;
				m_canRaiseSettlementSolutionChangedEvent = true;
				if (m_currentCustomer != null) { frmCustomerID2.Text = m_currentCustomer.Name; }

				FillFormValue();
				EnableControls(true);
				if (!m_errorMsg.IsNullOrWhiteSpace())
				{
					MessageBoxEx.Show(m_errorMsg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				}
			}));
		}

		#endregion

		#region -- 公布价自动匹配 --

		private void bgWorkerP_DoWork(object sender, DoWorkEventArgs e)
		{
			var settlementSolution = CurrentSettlementSolutions.Find(ss => ss.ID == m_selSettlementSolutionID);
			FillPriceInfos(settlementSolution);
		}

		private void bgWorkerP_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			this.BeginInvoke(new MethodInvoker(() =>
			{

				FillFormValue();
				EnableControls(true);
				if (!m_errorMsgP.IsNullOrWhiteSpace())
				{
					MessageBoxEx.Show(m_errorMsgP, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
					// 清空m_errorMsg错误信息
					m_errorMsg = null;
				}
			}));
		}

		#endregion

		#region 把获得的实体信息填充到表单显示

		private void FillFormValue()
		{

			GoodsCategory.Text = Convert.ToString(CurrentSettlement.GoodsCategoryEnum);
			frmRegion.Text = CurrentSettlement.Region;
			frmFuelModel.SelectedValue = CurrentSettlement.FuelModel;

			///判断燃油付费模式
			switch ((ExpressSettlementFuelModel)CurrentSettlement.FuelModel)
			{
				case ExpressSettlementFuelModel.IncludedFuelCosts:
					break;
				case ExpressSettlementFuelModel.PercentageTotalBilling:
					txtFuelData2.Value = Convert.ToInt32(CurrentSettlement.FuelData);
					break;
				case ExpressSettlementFuelModel.DiscountPercentageBilling:
					txtFuelData2.Value = Convert.ToInt32(CurrentSettlement.FuelData);
					break;
				case ExpressSettlementFuelModel.Cash:
					txtFuelData.Value = CurrentSettlement.FuelData;
					break;
				default:
					break;
			}
			frmFareCustomsHK.Value = CurrentSettlement.FareCustomsHK;
			frmWarehousingTemporary.Value = CurrentSettlement.WarehousingTemporary;
			frmCustomsDeclarationCost.Value = CurrentSettlement.CustomsDeclarationCost;
			frmOtherCost.Value = CurrentSettlement.OtherCost;
			frmDepartmentDiscount.Value = CurrentSettlement.DepartmentDiscount;
			frmCustomerDiscount.Value = CurrentSettlement.CustomerDiscount;
			frmCompanyDiscount.Value = CurrentSettlement.CompanyDiscount;
			frmDepartmentWeight.Text = CurrentSettlement.DepartmentWeight + "";
			frmCustomerWeight.Text = CurrentSettlement.CustomerWeight + "";
			frmSettleWeight.Text = CurrentSettlement.SettleWeight + "";
			frmProtoDepartmentWeight.Text = CurrentSettlement.ProtoDepartmentWeight + "";
			frmProtoCustomerWeight.Text = CurrentSettlement.ProtoCustomerWeight + "";
			frmProtoSettleWeight.Text = CurrentSettlement.ProtoSettleWeight + "";
			frmPrice.Text = CurrentSettlement.Price + "";
		}

		#endregion

	}
}